﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nature
{
    public partial class IdealGasMixture
    {
        void __calc_elxk(double[] elxk)
        {
            double totalSum = 0.0;
            double elSum = 0.0;
            var x = m_speciesMoleFractions.Array;
            var spel = Model.SpelMatrix;
            for (int iel = 0; iel < Nel; ++iel)
            {
                elSum = 0.0;
                for (int isp = 0; isp < Nsp; ++isp)
                {
                    elSum += x[isp] * spel[isp][iel];
                }
                elxk[iel] = elSum;
                totalSum += elSum;
            }
            for (int iel = 0; iel < Nel; ++iel) { elxk[iel] /= totalSum; }
        }

        void __calc_elyk(double[] elyk)
        {
            var ex = m_elementMoleFractions.Array;
            var ew = Model.ElementMolarMasses;
            double sum = 0.0;
            for (int iel = 0; iel < Nel; ++iel)
            {
                double add = ex[iel] * ew[iel];
                elyk[iel] = ex[iel] * ew[iel];
                sum += add;
            }
            for (int iel = 0; iel < Nel; ++iel) { elyk[iel] /= sum; }
        }

        void __calc_ck(double[] ck)
        {
            double csum = m_molarDensity.Value;
            var xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp) { ck[isp] = csum * xk[isp]; }
        }

        void __calc_xklog(double[] xklog)
        {
            var xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp) { xklog[isp] = Math.Log(1.0e-30 + xk[isp]); }
        }

        void __calc_ck_from_xk(double[] c)
        {
            double csum = m_molarDensity.Value;
            double[] x = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                c[isp] = x[isp] * csum;
            }
        }

        void __calc_yk_from_xk(double[] y)
        {
            double wmix = m_molarMass.Value;
            var w = Model.SpeciesMolarMasses;
            var x = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp) { y[isp] = x[isp] * w[isp] / wmix; }
        }


        void __calc_xk_from_yk(double[] x)
        {
            double wmix = m_molarMass.Value;
            var w = Model.SpeciesMolarMasses;
            var y = m_speciesMassFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp) { x[isp] = y[isp] / w[isp] / wmix; }
        }

        double __calc_molarmass_from_xk()
        {
            double[] x = m_speciesMoleFractions.Array;
            var w = Model.SpeciesMolarMasses;
            double sum = 0.0;
            for (int isp = 0; isp < Nsp; ++isp) { sum += x[isp] * w[isp]; }
            return sum;
        }

        double __calc_molarmass_from_yk()
        {
            double[] y = m_speciesMassFractions.Array;
            var w = Model.SpeciesMolarMasses;
            double sum = 0.0;
            for (int isp = 0; isp < Nsp; ++isp) { sum += y[isp] / w[isp]; }
            return sum;
        }


        double __calc_pressure_from_eos()
        {
            return Constants.Rgas * m_temperature.Value / m_molarDensity.Value;
        }

        double __calc_temperature_from_eos()
        {
            return m_pressure.Value / m_molarDensity.Value / Constants.Rgas;
        }

        double __calc_molardensity_from_eos()
        {
            return m_pressure.Value / m_temperature.Value / Constants.Rgas;
        }

        double __calc_massdensity_from_molardensity()
        {
            return m_molarDensity.Value * m_molarMass.Value;
        }

        double __calc_speedofsound()
        {
            double cp = m_cp.Value;
            double gamma = cp / (cp - 1.0d);
            return Math.Sqrt(gamma * Constants.Rgas * m_temperature.Value / m_molarMass.Value);
        }

        double __calc_temperaturelog()
        {
            return Math.Log(m_temperature.Value);
        }

        double __calc_pressureatmlog()
        {
            return Math.Log(m_pressure.Value / Constants.Atmosphere);
        }

        double __calc_molarcp_from_cp()
        {
            return m_cp.Value * Constants.Rgas;
        }

        double __calc_molarcv_from_cv()
        {
            return m_cv.Value * Constants.Rgas;
        }

        double __calc_molars_from_s()
        {
            return m_s.Value * Constants.Rgas;
        }

        double __calc_molarh_from_h()
        {
            return m_h.Value * Constants.Rgas * m_temperature.Value;
        }

        double __calc_molaru_from_u()
        {
            return m_u.Value * Constants.Rgas * m_temperature.Value;
        }

        double __calc_molarg_from_g()
        {
            return m_g.Value * Constants.Rgas * m_temperature.Value;
        }

        double __calc_molarf_from_f()
        {
            return m_f.Value * Constants.Rgas * m_temperature.Value;
        }


        double __calc_specificcp_from_cp()
        {
            return m_cp.Value * Constants.Rgas / m_molarMass.Value;
        }


        double __calc_specificcv_from_cv()
        {
            return m_cv.Value * Constants.Rgas / m_molarMass.Value;
        }

        double __calc_specifich_from_h()
        {
            return m_h.Value * Constants.Rgas * m_temperature.Value / m_molarMass.Value;
        }

        double __calc_specificu_from_u()
        {
            return m_u.Value * Constants.Rgas * m_temperature.Value / m_molarMass.Value;
        }

        double __calc_specificg_from_g()
        {
            return m_g.Value * Constants.Rgas * m_temperature.Value / m_molarMass.Value;
        }

        double __calc_specificf_from_f()
        {
            return m_f.Value * Constants.Rgas * m_temperature.Value / m_molarMass.Value;
        }

        double __calc_specifics_from_s()
        {
            return m_s.Value * Constants.Rgas / m_molarMass.Value;
        }

        double __calc_cp_from_cpk()
        {
            double cp = 0.0d;
            double[] cpk = m_speciesCp.Array;
            double[] xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                cp += xk[isp] * cpk[isp];
            }
            return cp;
        }

        double __calc_cv_from_cvk()
        {
            double cv = 0.0d;
            double[] cvk = m_speciesCv.Array;
            double[] xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                cv += xk[isp] * cvk[isp];
            }
            return cv;
        }

        double __calc_h_from_hk()
        {
            double h = 0.0d;
            double[] hk = m_speciesH.Array;
            double[] xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                h += xk[isp] * hk[isp];
            }
            return h;
        }


        double __calc_u_from_uk()
        {
            double u = 0.0d;
            double[] uk = m_speciesU.Array;
            double[] xk = m_speciesMoleFractions.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                u += xk[isp] * uk[isp];
            }
            return u;
        }

        double __calc_g_from_gk()
        {
            double g = 0.0d;
            double[] gk = m_speciesG.Array;
            double[] xk = m_speciesMoleFractions.Array;
            double[] xlofk = m_speciesMoleFractionsLog.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                g += xk[isp] * (gk[isp] + xlofk[isp]);
            }
            return g + m_pressureAtmLog.Value;
        }

        double __calc_f_from_fk()
        {
            double f = 0.0d;
            double[] fk = m_speciesF.Array;
            double[] xk = m_speciesMoleFractions.Array;
            double[] xlofk = m_speciesMoleFractionsLog.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                f += xk[isp] * (fk[isp] + xlofk[isp]);
            }
            return f + m_pressureAtmLog.Value;
        }

        double __calc_s_from_sk()
        {
            double s = 0.0d;
            double[] sk = m_speciesS.Array;
            double[] xk = m_speciesMoleFractions.Array;
            double[] xlofk = m_speciesMoleFractionsLog.Array;
            for (int isp = 0; isp < Nsp; ++isp)
            {
                s += xk[isp] * (sk[isp] - xlofk[isp]);
            }
            return s - m_pressureAtmLog.Value;
        }


        void __calc_cpk(double[] cpk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.Cp(m_temperature.Value, cpk);
        }

        void __calc_cvk(double[] cvk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.Cv(m_temperature.Value, cvk);
        }

        void __calc_hk(double[] hk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.H(m_temperature.Value, hk);
        }

        void __calc_uk(double[] uk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.U(m_temperature.Value, uk);
        }

        void __calc_sk(double[] sk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.S(m_temperature.Value, sk);
        }

        void __calc_gk(double[] gk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.G(m_temperature.Value, gk);
        }

        void __calc_fk(double[] fk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.F(m_temperature.Value, fk);
        }



        void __calc_molarcpk(double[] cpk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarCp(m_temperature.Value, cpk);
        }

        void __calc_molarcvk(double[] cvk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarCv(m_temperature.Value, cvk);
        }

        void __calc_molarhk(double[] hk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarH(m_temperature.Value, hk);
        }

        void __calc_molaruk(double[] uk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarU(m_temperature.Value, uk);
        }

        void __calc_molarsk(double[] sk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarS(m_temperature.Value, sk);
        }

        void __calc_molargk(double[] gk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarG(m_temperature.Value, gk);
        }

        void __calc_molarfk(double[] fk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.MolarF(m_temperature.Value, fk);
        }



        void __calc_specificcpk(double[] cpk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificCp(m_temperature.Value, cpk);
        }

        void __calc_specificcvk(double[] cvk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificCv(m_temperature.Value, cvk);
        }

        void __calc_specifichk(double[] hk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificH(m_temperature.Value, hk);
        }

        void __calc_specificuk(double[] uk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificU(m_temperature.Value, uk);
        }

        void __calc_specificsk(double[] sk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificS(m_temperature.Value, sk);
        }

        void __calc_specificgk(double[] gk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificG(m_temperature.Value, gk);
        }

        void __calc_specificfk(double[] fk)
        {
            var thermo = Model.IdealGasSpeciesThermoPotentials;
            thermo.SpecificF(m_temperature.Value, fk);
        }
    }
}
